package com.handinfo.uimenu;

import javax.microedition.lcdui.Graphics;

import com.handinfo.engine.AbstractGameScreen;
import com.handinfo.util.Tools;

public class ConcreteHyperLinker extends AbsHyperLinker {
	private final int W_BIAOQING = 16;// 一张切片的宽度及高度
	private final int ANCHOR = Graphics.TOP | Graphics.LEFT;
	//
	private byte[] m_types;// 标记类型
	private char[] m_markTypes;// 超链接类型
	private String[] m_ids;// 默认的Id
	private String[] m_contents_copy;// 解析出来的mark字符，和m_contents_hyper存储的字符串对象是一致的，只是数目，位置不同
	private String[][] m_contents;
	private int[] m_imageIds;
	private int[] m_xs;
	private int[] m_ys;
	private int[] m_endXs;
	private boolean[] m_isBolds;
	private boolean[] m_isUnderLines;
	private int[] m_colors;
	private int m_num_sum;// 具有的Item数目
	private int m_num_hyperLink;// 超链接数目

	public ConcreteHyperLinker(String str, int w, int h, int colorDefault) {
		super(str, w, h, colorDefault);
	}

	/**
	 * 解释数据，提供外部超链接对象
	 */
	protected void interpretate() {
		// 初始化
		int num = 30;// 预计选项的数目
		m_types = new byte[num];
		m_markTypes = new char[num];
		m_ids = new String[num];
		m_contents_copy = new String[num];
		m_contents = new String[num][];
		m_imageIds = new int[num];
		m_xs = new int[num];
		m_ys = new int[num];
		m_endXs = new int[num];
		m_isBolds = new boolean[num];
		m_isUnderLines = new boolean[num];
		m_colors = new int[num];
		// 放置信息，处理换行，mark，pic
		String content = m_content;
		String temp = null;
		int tempX = 0;
		int tempY = 0;// 当前计算的Y
		int startIndex = 0;
		int index = 0;// 指向item索引
		while ((temp = getSplitItemStr(content, startIndex)) != null) {
			byte type = getSplitItemType(temp);
			switch (type) {
			case TYPE_INTRE_CHANGEROW:// 换行
				// 替换换行符
				content = Tools.modifyString(content, temp, "");
				//
				tempX = 0;
				tempY += H_PRE;
				break;
			case TYPE_INTRE_STR_NOR:// 普通文字
				m_types[index] = type;
				m_xs[index] = tempX;
				m_ys[index] = tempY;
				m_colors[index] = m_color_nor_default;
				m_contents[index] = getSplitStrs(temp, m_xs[index],
						m_ys[index], m_w);
				m_endXs[index] = getEndX(m_contents[index], m_xs[index],
						m_ys[index], m_w);
				//
				tempX = m_endXs[index];
				tempY += (m_contents[index].length - 1) * H_PRE;
				//
				index++;
				startIndex += temp.length();
				break;
			case TYPE_INTRE_STR_HYPER:// 超链接文字
				m_types[index] = type;
				m_xs[index] = tempX;
				m_ys[index] = tempY;
				m_markTypes[index] = getMarkType(temp);
				m_ids[index] = getMarkIds(temp);
				m_colors[index] = getMarkColor(temp, m_markTypes[index]);
				m_isBolds[index] = getMarkBold(temp);
				m_isUnderLines[index] = getMarkUnderline(temp);
				String resoveStr = getMarkContent(temp);// 获得超链接内容
				content = Tools.modifyString(content, temp, resoveStr);// 替换
				m_contents_copy[index] = resoveStr;
				m_contents[index] = getSplitStrs(resoveStr, m_xs[index],
						m_ys[index], m_w);
				m_endXs[index] = getEndX(m_contents[index], m_xs[index],
						m_ys[index], m_w);
				//
				tempX = m_endXs[index];
				tempY += (m_contents[index].length - 1) * H_PRE;
				//
				if (m_ids[index] != MARK_VALUE_ID_DEFAULT) {
					m_num_hyperLink++;
				}
				index++;
				startIndex += resoveStr.length();
				break;
			case TYPE_INTRE_PIC:// 图片
				m_types[index] = type;
				int w = W_BIAOQING;
				if (tempX + w > m_w) {
					tempX = 0;
					tempY += H_PRE;
				}
				m_xs[index] = tempX;
				m_ys[index] = tempY;
				m_imageIds[index] = getImageId(temp);
				content = Tools.modifyString(content, temp, "");// 替换
				m_endXs[index] = m_xs[index] + w;
				tempX = m_endXs[index];
				//
				index++;
				break;
			default:
				throw new IllegalArgumentException("无此参数");
			}
		}
		m_num_sum = index;
	}

	/**
	 * 判断当前数据段是否是超链接类型
	 * 
	 * @param i
	 * @return
	 */
	private boolean isHyper(int i) {
		return m_types[i] == TYPE_INTRE_STR_HYPER
				&& m_ids[i] != MARK_VALUE_ID_DEFAULT;
	}

	protected void setTypes() {
		if (m_types == null) {
			return;
		}
		char[] types = new char[m_num_hyperLink];
		int index = 0;
		for (int i = 0; i < m_num_sum; i++) {
			if (isHyper(i)) {
				types[index] = m_markTypes[i];
				index++;
			}
		}
		m_types_hyper = types;
	}

	protected void setIds() {
		if (m_types == null) {
			return;
		}
		String[] ids = new String[m_num_hyperLink];
		int index = 0;
		for (int i = 0; i < m_num_sum; i++) {
			if (isHyper(i)) {
				ids[index] = m_ids[i];
				index++;
			}
		}
		m_ids_hyper = ids;
	}

	protected void setContents() {
		if (m_types == null) {
			return;
		}
		String[] contents = new String[m_num_hyperLink];
		int index = 0;
		for (int i = 0; i < m_num_sum; i++) {
			if (isHyper(i)) {
				contents[index] = m_contents_copy[i];
				index++;
			}
		}
		m_contents_hyper = contents;
	}

	/**
	 * <pic i=2></pic>
	 * 
	 * @param str
	 * @return
	 */
	private int getImageId(String str) {
		int index = str.indexOf(combine_pic_start);
		if (index == -1) {
			throw new IllegalArgumentException("无此参数");
		}
		int endIndex = str.indexOf(NOR_BRACKET_RIGHT);
		if (endIndex == -1) {
			throw new IllegalArgumentException("无此参数");
		}
		String num = str.substring(7, endIndex);
		return Integer.parseInt(num);
	}

	/**
	 * 获得从某处起，各个有效的ItemString
	 * 
	 * @param str
	 * @param startIndex
	 * @return
	 */
	private String getSplitItemStr(String str, int startIndex) {
		if (startIndex >= str.length()) {
			return null;
		}
		char firstChar = str.charAt(startIndex);
		if (firstChar == NOR_BRACKET_LEFT) {// < 标签文字
			if (str.indexOf(combine_mark_start, startIndex) == startIndex) {// mark
				int endIndex = str.indexOf(combine_mark_end)
						+ combine_mark_end.length();
				return str.substring(startIndex, endIndex);
			} else if (str.indexOf(combine_pic_start, startIndex) == startIndex) {// pic
				int endIndex = str.indexOf(combine_pic_end)
						+ combine_pic_end.length();
				return str.substring(startIndex, endIndex);
			} else {// nor
				return getNorStringFromStart(str, startIndex);
			}
		} else {
			if (String.valueOf(firstChar).equals(TYPE_CONTENT_CHANGEROW)) {// 换行
				return TYPE_CONTENT_CHANGEROW;
			} else {// nor
				return getNorStringFromStart(str, startIndex);// 从当前行获得
			}
		}
	}

	/**
	 * 
	 * 从开启处获得普通字符串
	 * 
	 * @param str
	 * @return
	 */
	private String getNorStringFromStart(String str, int startIndex) {
		// int markIndex = str.indexOf(combine_mark_start, startIndex);
		// int picIndex = str.indexOf(combine_pic_start, startIndex);
		// int type = (markIndex == -1 ? 0 : 2);
		// type += (picIndex == -1 ? 0 : 1);
		// switch (type) {
		// case 0://markIndex == -1 ，picIndex == -1
		// return str.substring(startIndex, str.length());
		// case 1://markIndex == -1，picIndex != -1 ;
		// return str.substring(startIndex, picIndex);
		// case 2://markIndex != -1，picIndex == -1 ;
		// return str.substring(startIndex, markIndex);
		// case 3://markIndex != -1，picIndex != -1 ;
		// int index = markIndex < picIndex ? markIndex : picIndex;
		// return str.substring(startIndex, index);
		// default:
		// throw new IllegalArgumentException("错误");
		// }

		int changerowIndex = str.indexOf(TYPE_CONTENT_CHANGEROW);
		int markIndex = str.indexOf(combine_mark_start);
		int picIndex = str.indexOf(combine_pic_start);
		int index = changerowIndex;
		if (markIndex != -1) {
			if (index == -1) {
				index = markIndex;
			} else {
				index = markIndex < index ? markIndex : index;
			}
		}
		if (picIndex != -1) {
			if (index == -1) {
				index = picIndex;
			} else {
				index = picIndex < index ? picIndex : index;
			}
		}
		if (index == -1) {
			index = str.length();
		}
		return str.substring(startIndex, index);
	}

	private byte getSplitItemType(String item) {
		if (item.equals(TYPE_CONTENT_CHANGEROW)) {
			return TYPE_INTRE_CHANGEROW;
		} else if (item.indexOf(combine_mark_end) != -1) {
			return TYPE_INTRE_STR_HYPER;
		} else if (item.indexOf(combine_pic_end) != -1) {
			return TYPE_INTRE_PIC;
		} else {
			return TYPE_INTRE_STR_NOR;
		}
	}

	/**
	 * 获得去除mark标签的文字,<mark t=m,i=11123,c=ffff00,b=1,u=1>标示内容</mark>
	 * 
	 * @param markStr
	 * @return
	 */
	private static final char getMarkType(String markStr) {
		int typeIndex = markStr.indexOf(String.valueOf(MARK_ATT_TYPE)
				+ String.valueOf(NOR_EQUAL));
		if (typeIndex == -1) {
			return URL_DEFAULT;
		}
		return markStr.charAt(typeIndex + 2);// 需在此处加判断，除了特定类型的类型，其余都是错误
	}

	/**
	 * <mark t=1,i=11123,c=ffff00,b=1,u=1>标示内容</mark>
	 * 
	 * @param content
	 * @return
	 */
	private static final String getMarkIds(String markStr) {
		int idIndex = markStr.indexOf(String.valueOf(MARK_ATT_ID)
				+ String.valueOf(NOR_EQUAL));
		if (idIndex == -1) {
			return MARK_VALUE_ID_DEFAULT;
		}
		int startIndex = idIndex + 2;
		int endIndex = markStr.indexOf(NOR_SYMBOL_COMMA, startIndex);
		if (endIndex == -1) {
			endIndex = markStr.indexOf(NOR_BRACKET_RIGHT, startIndex);
		}
		return markStr.substring(startIndex, endIndex);
	}

	/**
	 * 获得标记颜色<mark t=1,i=11123,c=ffff00,b=1,u=1>标示内容</mark>
	 * 
	 * @param markStr
	 * @return
	 */
	private static final int getMarkColor(String markStr, char type) {
		int colorIndex = markStr.indexOf(String.valueOf(MARK_ATT_COLOR)
				+ String.valueOf(NOR_EQUAL));
		if (colorIndex == -1) {// 若没有颜色
			switch (type) {
			case URL_ACTORITEM:
				return COLOR_DEFAULT_ACTORITEM;
			case URL_MAP:
				return COLOR_DEFAULT_MAP;
			case URL_PLAYER:
				return COLOR_DEFAULT_PLAY;
			case URL_NPC:
			case URL_WINDOW:
			case URL_DOWNLOAD:
				return COLOR_DEFAULT_NPC;
			case URL_DEFAULT:
			default:
				throw new IllegalArgumentException("标签类型错误 " + type);
			}
		} else {
			String color = markStr.substring(colorIndex + 2, colorIndex + 8);
			int Icolor = 0;
			try {
				Icolor = Integer.parseInt(color, 16);
			} catch (Exception ex) {
				Tools.debug(ex);
			}
			return Icolor;
		}
	}

	/**
	 * <mark t=1,i=11123,c=ffff00,b=1,u=1>标示内容</mark>
	 * 
	 * @param markStr
	 * @return
	 */
	private static final boolean getMarkBold(String markStr) {
		int boldIndex = markStr.indexOf(String.valueOf(MARK_ATT_BOLD)
				+ String.valueOf(NOR_EQUAL));
		if (boldIndex == -1) {
			return false;
		} else {
			char bold = markStr.charAt(boldIndex + 2);
			if (bold == '0') {
				return false;
			} else {
				return true;
			}
		}
	}

	/**
	 * <mark t=1,i=11123,c=ffff00,b=1,u=1>标示内容</mark>
	 * 
	 * @param markStr
	 * @return
	 */
	private static final boolean getMarkUnderline(String markStr) {
		int underlineIndex = markStr.indexOf(String.valueOf(MARK_ATT_UNDERLINE)
				+ String.valueOf(NOR_EQUAL));
		if (underlineIndex == -1) {
			return false;
		} else {
			char underline = markStr.charAt(underlineIndex + 2);
			if (underline == '0') {
				return false;
			} else {
				return true;
			}
		}
	}

	/**
	 * 获得标记内容<mark t=1,i=11123,c=ffff00,b=1,u=1>标示内容</mark>
	 * 
	 * @param markStr
	 * @return 标示内容
	 */
	private static final String getMarkContent(String markStr) {
		int startIndex = markStr.indexOf(NOR_BRACKET_RIGHT) + 1;
		int endIndex = markStr.indexOf(combine_mark_end, startIndex);
		return markStr.substring(startIndex, endIndex);
	}

	/**
	 * 将文字切割成字符串
	 * 
	 * @param temp
	 * @param startX
	 * @param startY
	 * @param w
	 * @return
	 */
	private String[] getSplitStrs(String temp, int startX, int startY, int w) {
		if (temp == null) {
			return null;
		}
		int sumW = AbstractGameScreen.s_font.stringWidth(temp);
		int num = 1;
		int left = sumW - (w - startX);
		if (left > 0) {
			num = 1 + (left + w - 1) / w;
		}
		String[] strs = new String[num];
		if (num == 1) {
			strs = new String[] { temp };
		} else {
			int maxW = 0;
			int startIndex = 0;
			char[] chars = temp.toCharArray();
			for (int i = 0; i < strs.length; i++) {
				if (i == 0) {
					maxW = w - startX;
				} else {
					maxW = w;
				}
				int endIndex = splitStr(chars, maxW, startIndex);
				strs[i] = temp.substring(startIndex, endIndex);
				startIndex = endIndex;
			}
		}
		return strs;
	}

	private int splitStr(char[] chars, int w, int startIndex) {
		int tempW = 0;
		for (int i = startIndex; i < chars.length; i++) {
			tempW += (AbstractGameScreen.s_font.charWidth(chars[i]));
			if (tempW >= w) {
				return i;
			}
		}
		return chars.length;
	}

	/**
	 * 获得结束X位置
	 * 
	 * @param strs
	 * @param startX
	 * @param startY
	 * @param w
	 * @return
	 */
	private int getEndX(String[] strs, int startX, int startY, int w) {
		if (strs == null) {
			throw new IllegalArgumentException("空");
		}
		if (strs.length == 1) {// 当行文本
			return startX + AbstractGameScreen.s_font.stringWidth(strs[0]);
		} else {
			return AbstractGameScreen.s_font.stringWidth(strs[strs.length - 1]);
		}
	}

	/**
	 * 修正坐标
	 */
	protected void correctXY() {
		int index_dis = countHyperIndex(m_index_hyper);
		if (index_dis == -1) {
			return;
		}
		while (m_ys[index_dis] + m_relY < 0) {
			m_relY += H_PRE;
		}
		boolean isCollect = false;// 是否修正
		int y = m_ys[index_dis] + m_contents[index_dis].length * H_PRE;
		while ((isCollect = y + m_relY < 0)) {// 顶部
			m_relY += H_PRE;
		}
		if (!isCollect) {
			while ((isCollect = y + m_relY > m_h)) {// 尾部
				m_relY -= H_PRE;
			}
		}
	}

	/**
	 * 获得相应的数据索引
	 * 
	 * @return
	 */
	private int countHyperIndex(int index_hyper) {
		if (index_hyper < 0) {
			return -1;
		}
		int index = 0;
		for (int i = 0; i < m_markTypes.length; i++) {
			if (isHyper(i)) {
				if (index == index_hyper) {
					return i;
				}
				index++;
			}
		}
		return -1;
	}

	/**
	 * 获得实际高度
	 */
	public int getRealHeight() {
		int lastIndex = m_num_sum - 1;
		lastIndex = lastIndex < 0 ? 0 : lastIndex;
		if (m_types[lastIndex] == TYPE_INTRE_PIC) {
			return m_ys[lastIndex] + W_BIAOQING;
		}
		return m_ys[lastIndex] + m_contents[lastIndex].length * H_PRE;
	}

	public void paintHyperLink(Graphics g, int x, int y) {
		int index_hyper = countHyperIndex(m_index_hyper);// 获得数据中的
		int ih_image = ((H_PRE - W_BIAOQING) >> 1);
		for (int i = 0; i < m_num_sum; i++) {
			int tempY = y + m_ys[i];//
			switch (m_types[i]) {
			case TYPE_INTRE_STR_HYPER:
			case TYPE_INTRE_STR_NOR:
				for (int j = 0, len = m_contents[i].length; j < len; j++) {
					int tempX = 0;
					int endX = m_w;
					if (j == 0) {// 起始位置
						tempX = m_xs[i];
					}
					if (j == len - 1) {
						endX = m_endXs[i];
					}
					paintStr(g, x + tempX, tempY, x + endX, m_contents[i][j],
							m_colors[i], m_isBolds[i], m_isUnderLines[i],
							m_types[i] == TYPE_INTRE_STR_HYPER
									&& i == index_hyper, ANCHOR);
					tempY += H_PRE;
				}
				break;
			case TYPE_INTRE_PIC:
				paintImage(g, x + m_xs[i], tempY + ih_image, m_imageIds[i],
						ANCHOR);
				break;
			}
		}
	}

	private void paintStr(Graphics g, int x, int y, int endX, String content,
			int color, boolean isBold, boolean isUnderderLine, boolean isSel,
			int anchor) {
		if (content == null) {
			return;
		}
		if (isSel) {
//			g.setColor(0x4f3c4a);
			g.setColor(0x958794) ;
			g.fillRect(x, y, endX - x, AbstractGameScreen.FONT_H);
		}
		g.setColor(color);
		if (isBold) {
			g.drawString(content, x - 1, y - 1, anchor);
			// g.drawString(content, x - 1, y + 1, anchor);
			// g.drawString(content, x + 1, y - 1, anchor);
			// g.drawString(content, x + 1, y + 1, anchor);
		}
		g.drawString(content, x, y, anchor);
		if (isUnderderLine) {
			int bootomY = y + AbstractGameScreen.FONT_H;
			g.drawLine(x, bootomY, endX, bootomY);
		}
	}

	private void paintImage(Graphics g, int x, int y, int imageId, int anchor) {
		int clipX = g.getClipX();
		int clipY = g.getClipY();
		int clipW = g.getClipWidth();
		int clipH = g.getClipHeight();
		int rowIndex = imageId / 4;
		int colIndex = imageId % 4;
		g.setClip(x, y, W_BIAOQING, W_BIAOQING);
		g.drawImage(UIManager.IMAGE_BIAOQIAN, x - (colIndex * W_BIAOQING), y
				- (rowIndex * W_BIAOQING), 0);
		g.setClip(clipX, clipY, clipW, clipH);
	}
}
